package com.ipan.poi.utils;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.io.UnsupportedEncodingException;
import java.text.MessageFormat;
import java.util.Date;

import org.apache.commons.lang.time.DateFormatUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 文件记录工具基类，支持多线程并发；
 * 支持直接写入文件（如果写入频率比较高，频繁读写文件性能会比较低）；
 * 支持先保存到内存，然后再刷新到文件（推荐）；
 * 
 * @author iPan
 * @version 2013-04-02
 */
public abstract class PoiAppFileLogger {
	// 状态
	public static final String MSG_SUCCESS = "成功";
	public static final String MSG_FAIL = "失败";
	public static final String EOL = System.getProperty("line.separator");
	public static final String MSG_HR = "-------------------------------------------------------------" + EOL;
	public static final String DEFAULT_DATE_PATTERN = "yyyy/MM/dd HH:mm:ss";
	
	protected ThreadLocal<StringBuilder> cache = new ThreadLocal<StringBuilder>() {
        protected synchronized StringBuilder initialValue() {
            return new StringBuilder();
        }};

    protected String filePath = null;
    
    protected Logger logger = LoggerFactory.getLogger(getClass());
    
    public PoiAppFileLogger(String filePath) {
    	this.filePath = filePath;
    }

    public void appendToCache(String pattern, Object ... args) {
		String text = this.getText(pattern, args);
		StringBuilder buf = this.getCache();
		buf.append(text);
	}
	
	public void appendToCache(String text) {
		if (text == null) {
			return ;
		}
		StringBuilder buf = this.getCache();
		buf.append(text);
	}
	
	public void appendToCache(String[] args) {
		if (args == null || args.length < 1) {
			return ;
		}
		StringBuilder buf = this.getCache();
		for (String s : args) {
			buf.append(s);
		}
	}
	
	public void flush() {
		write(this.getCache().toString());
		cleanCache();
	}
	
	public synchronized void write(String pattern, Object ... args) {
		String text = this.getText(pattern, args);
		write(text);
	}
	
	public synchronized void write(String str) {
		PrintStream print = null; 
		try {
			print = getPrintStream();
			print.print(str);
		} catch (Exception e) {
			throw new RuntimeException("写入文件[" + filePath + "]失败！", e);
		} finally {
			if (print != null) {
				print.close();
			}
		}
	}
	
	public String getText(String pattern, Object ... args) {
		return MessageFormat.format(pattern, args) + EOL;
	}
	
	public String getDefaultDateStr() {
		return getDateStr(DEFAULT_DATE_PATTERN);
	}
	
	public String getDateStr(String pattern) {
		return DateFormatUtils.format(new Date(), pattern);
	}
	
	public StringBuilder getCache() {
		return this.cache.get();
	}
	
	public void cleanCache() {
		this.cache.remove();
	}
	
	public String getFilePath() {
		return filePath;
	}

	private PrintStream getPrintStream() throws UnsupportedEncodingException, FileNotFoundException {
		File file = new File(filePath);
		if (!file.exists()) {
			PoiFileHelper.createFile(file.getAbsolutePath(), file.getAbsolutePath().length());
		}
		return new PrintStream(new FileOutputStream(file, true), true, "UTF-8");
	}
}
